#pragma once
/**
 * @file Acceptor.hpp
 * @author 1102403684@qq.com
 * @brief
 * @version 0.1
 * @date 2024-10-15
 *
 * @copyright Copyright (c) 2024
 *
 */

#include "../common/Socket.hpp"

#include "Channel.hpp"


class EventLoop;
class Acceptor
{
public:
    using AcceptCallBack = std::function<void(int /*fd*/)>;
    Acceptor(EventLoop *loop, int port) : loop_(loop), socket_(init_socket(port)), channel_(loop, socket_.get_fd())
    {
        channel_.set_read_callback(std::bind(&Acceptor::handle_read, this));
        //不应该启动读事件放入构造函数中执行 因为此时可能会立刻有读描述符就绪 但由于accept_callback还未就绪 会造成资源泄漏
        // channel_.enable_read_event();
    }

    void set_accept_callback(const AcceptCallBack &cb)
    {
        accept_callback_ = cb;
    }

    void accept()
    {
        channel_.enable_read_event();
    }

private:
    Socket socket_;   // 创建套接字
    Channel channel_; // 对监听套接字的事件管理
    EventLoop *loop_; // 对监听套接字的事件监控
    AcceptCallBack accept_callback_;

private:
    // 对监听套接字设置的读事件回调函数
    void handle_read() 
    {
        int newfd = socket_.accept();
        if(newfd < 0){
            return;
        }
        LOG_TRACE("Accept 了一个新连接 {}", newfd);
        if(accept_callback_) accept_callback_(newfd);
    }

    int init_socket(int port)
    {
        bool ret = socket_.create_server_socket(port); // 创建服务器连接
        assert(ret == true);
        return socket_.get_fd();
    }
};